import pprint


import rai.sem.parse_util as parse_util

from rai.logger.logger import *
from rai.util.util import *

import gen_grammar
import gen_valuation

import test.wordnet.testwordnet as testwordnet

class SentenceHandler:
    """
        This class determines what kind a sentence we are dealing with 
        and how to create the appropriate grammar rules
    """
    
    def __init__(self, parsed_sentence, world):
        self.parsed_sentence = parsed_sentence
        self.vpParts = parse_util.getParts('VP', self.parsed_sentence) # list of VP-parts
        self.npParts = parse_util.getParts('NP', self.parsed_sentence) # list of NP-parts
        self.ppParts = parse_util.getParts('PP', self.parsed_sentence) # list of PP-parts
        self.world = world
        self.information = SentenceAnalyzerInfo()
    
    
    def analyzeSentence(self):
        """
            Analyzes the sentence
        """
        if (parse_util.sentenceHasSpecialVerb(self.parsed_sentence)):
            # this is a special kind of sentence (has verb 'to be')
            debug("special verb sentence")
            current_information = ["has special verb part"]
            self.information.logs.extend(current_information)
            
            self.__handleSpecialVerbSentence()
            
        else:
            debug("standard sentence")
            current_information = ["standard sentence"]
            self.information.logs.extend(current_information)
            
            self.__handleStandardVerbSentence()
        
        return self.information
        
    def __handleStandardVerbSentence(self, trace = 0):
        """
            generates valuation
            verb => (NP[0], NP[1])
        """
        
        if len(self.vpParts) == 1 and len(self.npParts) == 2 and len(self.ppParts) == 0:
            # one verb part and two NP parts
            self.information.logs.extend(["standard simple verb"])
            self.verbStandardSimple()
        elif len(self.vpParts) == 0:
            # No VP Part, the sentence has no verb, how do we create facts from it?
            self.information.logs.extend(["no verb"])
        else:
            self.information.logs.extend(["standard other (lookup) verb"])

            #self.verbExtended()
            debug("standard other (lookup) verb")

            # get the first VP
            firstVPart = self.vpParts[0]
            debug(firstVPart)
            # get the first VERB in this part
            firstVerbTuple = firstVPart[1]
            debug(firstVerbTuple)
            # look it up in verbnet and get its syntax definition
            verbnetutil = testwordnet.VerbnetUtil()
            matches = verbnetutil.getSyntaxStructures(self.parsed_sentence, trace = trace)
            
            if len(matches) == 0:
                debug("No matching frame!")
            #print len(matches)
            debug("#Matches: " + str(len(matches)))
            
            if trace == 5:
                pp = pprint.PrettyPrinter(indent=4)
                pp.pprint(matches)
            vp_size = len(self.vpParts)
            self.information.logs.extend(["vp_size:"+str(vp_size)])

            np_size = len(self.npParts)
            self.information.logs.extend(["np_size:"+str(np_size)])
            
            pp_size = len(self.ppParts)
            self.information.logs.extend(["pp_size:"+str(pp_size)])
            
            
                        
    def __handleSpecialVerbSentence(self):
        # create value
        # npParts[0] is the subject (e.g. John)
        # npParts[1] is the property (e.g. singer)
        
        if len(self.npParts) == 2:
            # Two NP parts and verb 'to be'
            # e.g. 'john is a bird'
            self.verbToBeProperty()
            return ["to be - property"]
        elif len(self.npParts) == 1 and len(self.ppParts) == 1:
            # Two NP parts and verb 'to be'
            # e.g. 'john is in the kitchen'
            self.verbToBeLocation()
            return ["to be - location"]
        else:
            debug("Other special verb")
            information = []
            
            vp_size = len(self.vpParts)
            information.extend(["vp_size:"+str(vp_size)])

            np_size = len(self.npParts)
            information.extend(["np_size:"+str(np_size)])
            
            pp_size = len(self.ppParts)
            information.extend(["pp_size:"+str(pp_size)])
            
            return information


    
    def verbToBeProperty(self):
        """ 
            verb: 'to be'
            semantic meaning: first NP part has the second NP as a property. 
            E.g.: the result in FOL should be 'singer(Madonna)'
        """
        debug("to be - property")
        # TODO: add adjectives as propery to Noun (e.g. the big red house => big(house), red(house))
        subject = parse_util.stripNoun(self.npParts[0]) # removes adjectives, determiners (e.g.: the big red house => house)
    
        np_property = parse_util.stripNoun(self.npParts[1])
        subject = concatTupleListIndex(subject, 0)
        np_property = concatTupleListIndex(np_property, 0)
            #subject = word
            #np_property = np_property[0]
    
        #rhv = gen_valuation.addEntityToWorld(subject, self.world) # john => b1
        #gen_valuation.addEntityPropertyToWorld(rhv, np_property, self.world) # drunk => {b1}
             
        # check if np_property exists in the grammar.lexicon()
        gen_grammar.addPopertyToGrammar(subject, self.world, tags=self.npParts[0])
        gen_grammar.addPopertyToGrammar(np_property, self.world, tags=self.npParts[1])
                
                
    def verbToBeLocation(self):
        """ verb: 'to be'
            semantic meaning: first NP is the subject, PP is the location
        """
        debug("to be - location ")
        
        subject = parse_util.stripNoun(self.npParts[0]) # removes adjectives, determiners (e.g.: the big red house => house)
        location = parse_util.stripNoun(self.ppParts[0])
        print "suzie: " + str(subject)
        print "lcoation: " + str(location)
        #subject = convertNPPartToEntity(npParts[0])
        #location = convertNPPartToEntity(ppParts[0])
        property = self.ppParts[0][1:][0]
        #print subject, location, property
    
        subject = concatTupleListIndex(subject, 0)
        location = concatTupleListIndex(location, 0)        
        #subject = subject[0]
        #location = location[0]
        property = property[0]
              
        rhv = gen_valuation.addEntityToWorld(subject, self.world) # john => b1
        loc = gen_valuation.addEntityToWorld(location, self.world) # Noosa => n
        
        gen_valuation.addPropertyWith2Entities(property, rhv, loc, self.world)
            
        gen_grammar.addPopertyToGrammar(property, self.world)
        pass
    
    def verbStandardSimple(self):
        """
            Simple sentence construction:
            1 Verb part
            2 NP parts
            e.g.: John loves Susan
        """
        debug("standard verb - Transitive verbs")
        subject_tuples = parse_util.stripNoun(self.npParts[0]) # removes adjectives, determiners (e.g.: the big red house => house)
        object_tuples = parse_util.stripNoun(self.npParts[1])
        debug("subject: " + str(subject_tuples))
        debug("object: " + str(object_tuples))    
        #print subject, object
        #object = convertNPPartToEntity(npParts[0]) # nominativus, onderwerp
        #subject = convertNPPartToEntity(npParts[1]) # accusativus/dativus, lijdend voorwerp/medewerkend voorwerp
    
        verbPart = self.vpParts[0]
        property_tuple = verbPart[1:][-1]
    
        subject_words = concatTupleListIndex(subject_tuples, 0)
        object_words = concatTupleListIndex(object_tuples, 0)
        #object = object[0]
        #subject = subject[0]
        property = concatTupleListIndex(property_tuple, 0)

        property = property.lower()
        debug(str((subject_words, property, object_words)))
        # valuation:
        #first = gen_valuation.addEntityToWorld(subject_words, self.world) # john => b1
        #second = gen_valuation.addEntityToWorld(object_words, self.world) # susan => s2
        #gen_valuation.addPropertyWith2Entities(property, first, second, self.world)
        
        # grammar:
        (isNew1, rule1) = gen_grammar.addTVToGrammar(property, self.world) # Transitive verbs      
        (isNew2, rule2) = gen_grammar.addPopertyToGrammar(subject_words, self.world, tags = self.npParts[0])
        (isNew3, rule3) = gen_grammar.addPopertyToGrammar(object_words, self.world, tags = self.npParts[1])
         
class SentenceAnalyzerInfo:
    
    def __init__(self):
        self.logs = []